package main

import (
	authpb "car_rental/auth/api/gen/v1"
	"car_rental/auth/auth"
	"car_rental/auth/dao"
	"car_rental/auth/token"
	"car_rental/shared/server"
	"car_rental/wechat"
	"context"
	"crypto/rsa"
	"github.com/dgrijalva/jwt-go"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"io"
	"log"
	"os"
	"time"
)

const (
	mongoURL      = "mongodb://root:123456@localhost:47017/?authSource=car_rental&readPreference=primary&ssl=false"
	mongoDatabase = "car_rental"
)

func main() {

	logger, err := zap.NewDevelopment()

	if err != nil {
		log.Fatalf("创建zap.logger失败: %v", err)
	}

	mc := connectMongoDB(err, logger)

	// 从文件中读取私钥
	privateKey := readPrivateKey(logger)

	// 启动用户认证服务
	logger.Sugar().Fatal(server.RunGrpcServer(&server.Config{
		Name:   "auth",
		Addr:   "localhost:8081",
		Logger: logger,
		RegisterFunc: func(s *grpc.Server) {
			authpb.RegisterAuthServiceServer(s, &auth.Service{
				Logger: logger,
				OpenIDResolver: &wechat.Service{
					AppSecret: "c51ec3b3a24879e730f74be4511c7234",
					AppID:     "wx900bfa78f8e839d0",
				},
				Mongo:          dao.NewMongo(mc.Database(mongoDatabase)),
				TokenExpire:    2 * time.Hour,
				TokenGenerator: token.NewJwtTokenGen("car_rental/auth", privateKey),
			})
		},
	}))

}

// 连接MongoDB
func connectMongoDB(err error, logger *zap.Logger) *mongo.Client {

	c := context.Background()

	mc, err := mongo.Connect(c, options.Client().ApplyURI(mongoURL))

	if err != nil {
		logger.Fatal("无法连接mongodb: %v", zap.Error(err))
	}

	return mc

}

// 从文件中读取私钥
func readPrivateKey(logger *zap.Logger) *rsa.PrivateKey {

	pkFile, err := os.Open("auth/rsa/rsa_private_key.pem")

	if err != nil {
		logger.Fatal("无法打开私钥文件", zap.Error(err))
	}

	pkBytes, err := io.ReadAll(pkFile)

	if err != nil {
		logger.Fatal("无法读取私钥文件", zap.Error(err))
	}

	privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(pkBytes)

	if err != nil {
		logger.Fatal("无法解析私钥文件", zap.Error(err))
	}

	return privateKey
}
